package com.jinhua.huaojcodesandbox.utils;

import cn.hutool.core.date.StopWatch;
import cn.hutool.core.util.StrUtil;
import com.jinhua.huaojcodesandbox.model.ExecuteMessage;

import java.io.*;
import java.nio.charset.StandardCharsets;

/**
 * 获取进程执行信息工具类
 */
public class ProcessUtils {
    /**
     * 获取进程执行信息
     *
     * @param executeProcess 执行的代码
     * @return 返回执行信息
     */
    public static ExecuteMessage getProcessRunMessage(Process executeProcess, String action) throws UnsupportedEncodingException {
        ExecuteMessage executeMessage = new ExecuteMessage();
        Integer exitValue = -1;
        StringBuilder outputStringBuilder = new StringBuilder();
        StringBuilder errorOutputStringBuilder = new StringBuilder();
        //执行cmd代码并获取返回值
        try {
            exitValue = executeProcess.waitFor();
            if (exitValue == 0) {
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(executeProcess.getInputStream(),"GBK"));
                String outputLine;
                while ((outputLine = bufferedReader.readLine()) != null) {
                    outputStringBuilder.append(outputLine);
                }
                bufferedReader.close();
            } else {
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(executeProcess.getInputStream(),"GBK"));
                String outputLine;
                while ((outputLine = bufferedReader.readLine()) != null)  {
                    outputStringBuilder.append(outputLine);
                }
                bufferedReader.close();
//                获取错误信息
                BufferedReader errorBufferedReader = new BufferedReader(new InputStreamReader(executeProcess.getErrorStream(),"GBK"));
                String compileErrorOutputLine;
//                逐行读取
                while ((compileErrorOutputLine = errorBufferedReader.readLine()) != null) {

                    errorOutputStringBuilder.append(compileErrorOutputLine);
                }
                errorBufferedReader.close();
            }
            executeProcess.destroy();
        } catch (IOException | InterruptedException e) {
            throw new RuntimeException(e);
        }

        executeMessage.setExitValue(exitValue);
        executeMessage.setMessage(outputStringBuilder.toString());
        executeMessage.setErrorMessage(errorOutputStringBuilder.toString());
        if (exitValue == 0) {
            System.out.println( action +  "成功" + outputStringBuilder);
        } else {
            System.out.println( action + "失败 " + errorOutputStringBuilder);
        }
        return executeMessage;
    }

    /**
     * 执行进程并获取信息
     * @param executeProcess 执行程序
     * @return 返回执行信息
     */
    public static ExecuteMessage runInteractProcess(Process executeProcess, String input, String action) {
        ExecuteMessage executeMessage = new ExecuteMessage();
        Integer exitValue = -1;
        StringBuilder errorOutputStringBuilder = new StringBuilder();
        StringBuilder outputStringBuilder = new StringBuilder();
        String[] s = input.split(" ");
        String args = StrUtil.join("\n", s) + "\n";
        long maxTime = 0l;

        try {
//            todo 一个例子一个时间
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            InputStream inputStream = executeProcess.getInputStream();
            OutputStream outputStream = executeProcess.getOutputStream();
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
            outputStreamWriter.write(args);
//            清空缓冲区
            outputStreamWriter.flush();

            exitValue = executeProcess.waitFor();

//            正常退出
            if (exitValue == 0) {
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(executeProcess.getInputStream(), StandardCharsets.UTF_8));

                String compileOutputLine;
//                逐行读取
                while ((compileOutputLine = bufferedReader.readLine()) != null) {
                    outputStringBuilder.append(compileOutputLine);
                }
            }else {
//                分批获取进程的输出
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(executeProcess.getInputStream(),"GBK"));

                String executeOutputLine;
//                逐行读取
                while (true) {
                    try {
                        if ((executeOutputLine = bufferedReader.readLine()) == null) break;
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                    outputStringBuilder.append(executeOutputLine);
                }

//                获取错误信息
                BufferedReader errorBufferedReader = new BufferedReader(new InputStreamReader(executeProcess.getErrorStream(),"GBK"));
                String runErrorOutputLine;
//                逐行读取
                while ((runErrorOutputLine = errorBufferedReader.readLine()) != null) {

                    errorOutputStringBuilder.append(runErrorOutputLine);
                }
                executeMessage.setErrorMessage(errorOutputStringBuilder.toString());

            }
            if (exitValue == 0) {
                System.out.println( action +  "成功" + outputStringBuilder);
            } else {
                System.out.println( action + "失败 " + errorOutputStringBuilder);
            }
            executeMessage.setExitValue(exitValue);
            executeMessage.setMessage(outputStringBuilder.toString());

            stopWatch.stop();
            long time = stopWatch.getLastTaskTimeMillis();
            executeMessage.setTime(time);

//            inputStream.close();
//            outputStream.close();
//            outputStreamWriter.close();

        } catch (IOException | InterruptedException e) {
            throw new RuntimeException(e);
        }
        executeMessage.setTime(maxTime);
        return executeMessage;

    }


}
